﻿using UnityEngine;
using System.Collections;
using System;
using System.Threading;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace protoNet
{
    public class JFSocket
    {
        //Socket客户端对象  
        private Socket clientSocket;
        //JFPackage.WorldPackage是我封装的结构体，  
        //在与服务器交互的时候会传递这个结构体  
        //当客户端接到到服务器返回的数据包时，我把结构体add存在链表中。  
        //public List<JFPackage.WorldPackage> worldpackage;
        //单例模式  
        private static JFSocket Instance;
        public static JFSocket GetInstance()
        {
            if (Instance == null)
            {
                Instance = new JFSocket();
            }
            return Instance;
        }

        //单例的构造函数  
        JFSocket()
        {
            //创建Socket对象， 这里我的连接类型是TCP  
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //服务器IP地址  
            Debug.Log( SaveHallData.Instance.host);
            IPAddress ipAddress = IPAddress.Parse("192.168.0.254");
            //服务器端口  
            IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 1002);
            //这是一个异步的建立连接，当连接建立成功时调用connectCallback方法  
            IAsyncResult result = clientSocket.BeginConnect(ipEndpoint, new AsyncCallback(connectCallback), clientSocket);
            clientSocket.Connect(ipEndpoint);
            Debug.Log("*********************************************");
            //这里做一个超时的监测，当连接超过5秒还没成功表示超时  
            bool success = result.AsyncWaitHandle.WaitOne(5000, true);
            if (!success)
            {
                //超时  
                Closed();
                Debug.Log("connect Time Out");
            }
            else
            {
                //与socket建立连接成功，开启线程接受服务端数据。  
                //worldpackage = new List<JFPackage.WorldPackage>();
                Thread thread = new Thread(new ThreadStart(ReceiveSorket));
                thread.IsBackground = true;
                thread.Start();
                Debug.Log("11111111111111111111111111");
            }
        }
        private void connectCallback(IAsyncResult asyncConnect)
        {
            _G.Print("connectSuccess");
        }

        private void ReceiveSorket()
        {
            //在这个线程中接受服务器返回的数据  
            while (true)
            {

                if (!clientSocket.Connected)
                {
                    //与服务器断开连接跳出循环  
                    _G.Print("Failed to clientSocket server.");
                    clientSocket.Close();
                    break;
                }
                try
                {
                    //接受数据保存至bytes当中  
                    byte[] bytes = new byte[4096];
                    //Receive方法中会一直等待服务端回发消息  
                    //如果没有回发会一直在这里等着。  
                    int i = clientSocket.Receive(bytes);
                    if (i <= 0)
                    {
                        clientSocket.Close();
                        break;
                    }

                    //这里条件可根据你的情况来判断。  
                    //因为我目前的项目先要监测包头长度，  
                    //我的包头长度是2，所以我这里有一个判断  
                    MsgReader.ReadMessage(bytes);

                }
                catch (Exception e)
                {
                    _G.Print("Failed to clientSocket error." + e);
                    clientSocket.Close();
                    break;
                }
            }
        }

        public void SendMessage(byte[]buttf)
        {

            Debug.Log("44444444444444444444"+ buttf[3] + "        " +buttf[4]);

            if (!clientSocket.Connected)
            {
                Debug.Log("2222222222222222222222");
                clientSocket.Close();
                return;
            }
            try
            {
                clientSocket.Send(buttf,0,buttf.Length,SocketFlags.None);
                
                Debug.Log("33333333333333333333");
                //向服务端异步发送这个字节数组  
                //IAsyncResult asyncSend = clientSocket.BeginSend(buttf, 0, buttf.Length, SocketFlags.None, new AsyncCallback(sendCallback), clientSocket);
                //监测超时  
                //bool success = asyncSend.AsyncWaitHandle.WaitOne(5000, true);
                //if (!success)
                //{
                //    clientSocket.Close();
                //    _G.Print("Time Out !");
                //}

            }
            catch (Exception e)
            {
                _G.Print("send message error: " + e);
            }
        }
        private void sendCallback(IAsyncResult asyncSend)
        {            
            _G.Print("sendCallback");
        }
        //关闭Socket  
        public void Closed()
        {

            if (clientSocket != null && clientSocket.Connected)
            {
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
            }
            clientSocket = null;
        }
    }
}